package com.android.fragmentdemo.thread12;

import org.junit.Test;

import java.util.concurrent.locks.ReentrantLock;

public class Demo12 {
    @Test
    public void testRunnable() {

        final ReentrantLock reentrantLock = new ReentrantLock();
        final NonReentrantLock nonReentrantLock = new NonReentrantLock();

        Thread thread1 = new Thread(new ReentrantTask(reentrantLock),"t0");
        Thread thread2 = new Thread(new NonReentrantTask(nonReentrantLock), "t1");

        thread1.start();
        thread2.start();

        try {
            Thread.sleep(5 * 1000);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    static class ReentrantTask implements Runnable {

        private final ReentrantLock lock;

        public ReentrantTask(ReentrantLock lock) {
            this.lock = lock;
        }

        @Override
        public void run() {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "---进入可重入锁临界区");
                criticalSection();
                System.out.println(Thread.currentThread().getName() + "---离开可重入锁临界区");
            } finally {
                lock.unlock();
            }
        }

        private void criticalSection() {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "---正在执行可重入锁临界区域");
            } finally {
                lock.unlock();
            }
        }
    }

    static class NonReentrantTask implements Runnable {

        private final NonReentrantLock lock;

        public NonReentrantTask(NonReentrantLock lock) {
            this.lock = lock;
        }

        @Override
        public void run() {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "///进入不可重入锁临界区");
                criticalSection();
                System.out.println(Thread.currentThread().getName() + "///离开不可重入锁临界区");
            } finally {
                lock.unlock();
            }
        }

        private void criticalSection() {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "///正在执行不可重入锁临界区域");
            } finally {
                lock.unlock();
            }
        }
    }

    static class NonReentrantLock {
        private boolean isLock = false;

        public synchronized void lock() {
            while (isLock) {
                try {
                   wait();
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                }
            }
            isLock = true;
        }

        public synchronized void unlock() {
            isLock = false;
            notify();
        }
    }
}
